/**
  ******************************************************************************
  * @file    tc32l010_adc.c
  * @author  CHIPAT Application Team
  * @brief   This file provides firmware functions to manage the following
  *          functionalities of the Analog to Digital Convertor (ADC)
  @verbatim
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tc32l010_adc.h"

/** @addtogroup XS32L010_StdPeriph_Driver
  * @{
  */

/* Exported functions ---------------------------------------------------------*/
/**
  * @brief  Deinitializes ADC1 peripheral registers to their default reset values.
  * @param  None
  * @retval None
  */
void ADC_DeInit(void)
{
    /* Enable ADC reset state */
    RCC_APBPeriphResetCmd(RCC_APBPeriph_ADC, ENABLE);

    /* Release ADC from reset state */
    RCC_APBPeriphResetCmd(RCC_APBPeriph_ADC, DISABLE);

}

/**
  * @brief  Initializes the ADCx peripheral according to the specified parameters
  *         in the ADC_InitStruct.
  * @note   This function is used to configure the global features of the ADC (
  *         continuous mode activation, External trigger source and edge).
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains
  *         the configuration information for the specified ADC peripheral.
  * @retval The ErrorStatus of ADC_Init (ERROR or SUCCESS).
  */
ErrorStatus ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
{
    uint32_t tmpreg = 0;
    uint32_t status = SUCCESS;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode));
    assert_param(IS_ADC_TRIGS_SEL(ADC_InitStruct->ADC_TrigConv));
    assert_param(IS_ADC_CMPGAIN(ADC_InitStruct->ADC_CMPGain));
    assert_param(IS_ADC_OFFSET(ADC_InitStruct->ADC_Offset));
    assert_param(IS_ADC_FIRST_SAMPLE(ADC_InitStruct->ADC_FirstSampleTime));
    assert_param(IS_ADC_CONTINUOUS_CONV_CNT(ADC_InitStruct->ADC_Cnt));
    assert_param(IS_ADC_OFFSET(ADC_InitStruct->ADC_Offset));

    /* Get the ADCx CR0 value */
    tmpreg = ADCx->CR0;

    /* Clear SDIF and MODE bits */
    tmpreg &= ~(ADC_CR0_RATIO | ADC_CR0_GCMP | ADC_CR0_OFFSET);

    /*---------------------------- ADCx CR Configuration ---------------------*/
    /* Write to ADCx CR0 */
    ADCx->CR0 = tmpreg | ((ADC_InitStruct->ADC_Ratio << 17)| \
                          (ADC_InitStruct->ADC_CMPGain << 19)| \
                          (ADC_InitStruct->ADC_Offset << 20));

    ADCx->CR1 = (ADC_InitStruct->ADC_ContinuousConvMode << 8) | (ADC_InitStruct->ADC_AccEn << 9) |\
                ADC_InitStruct->ADC_TrigConv;

    tmpreg = ADCx->CR2;

    tmpreg &= ~(ADC_CR2_ADCCNT);

    ADCx->CR2 = tmpreg | (ADC_InitStruct->ADC_Cnt << 8);

    tmpreg = ADCx->TIME;

    tmpreg &= ~ADC_TIME_FIRST_SAMPLE;

    ADCx->TIME = tmpreg | ADC_InitStruct->ADC_FirstSampleTime;

    if(status)
    {
        return SUCCESS;
    }
    else
    {
        return ERROR;
    }
}

/**
  * @brief  Fills each ADC_InitStruct member with its default value.
  * @note   This function is used to initialize the global features of the ADC (
  *         continuous mode activation, External trigger source and edge).
  * @param  ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will
  *         be initialized.
  * @retval None
  */
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct)
{
    /* Reset ADC init structure parameters values */
    /* Initialize the ADC_ContinuousConvMode member */
    ADC_InitStruct->ADC_ContinuousConvMode = DISABLE;

    /* Initialize the ADC_TrigConv member */
    ADC_InitStruct->ADC_TrigConv = ADC_TRIGS_SEL_NONE;

    /* Initialize the ADC_Offset member */
    ADC_InitStruct->ADC_Offset = 0;

    /* Initialize the ADC_CMPGain member */
    ADC_InitStruct->ADC_CMPGain = 0;

    /* Initialize the ADC_Cnt member */
    ADC_InitStruct->ADC_Cnt = 0;

    /* Initialize the ADC_AccEn member */
    ADC_InitStruct->ADC_AccEn = 0;

    /* Initialize the ADC_FirstSampleTime member */
    ADC_InitStruct->ADC_FirstSampleTime = 3;
}

/**
  * @brief  Enables or disables the specified ADC peripheral.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the ADCx peripheral.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* Set the ADEN bit to Enable the ADC peripheral */
        ADCx->CR0 |= (uint32_t)ADC_CR0_ADCEN;
    }
    else
    {
        /* Set the ADDIS to Disable the ADC peripheral */
        ADCx->CR0 &= (uint32_t)(~ADC_CR0_ADCEN);
    }
}

/**
  * @}
  */

/**
  * @brief  set the ADC startup time.
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  ADC_CLK: the ADC CLK.
  *
  * @retval None
  */
void ADC_SetStartupTime(ADC_TypeDef* ADCx, uint32_t ADC_CLK)
{
    uint32_t reg;
    uint32_t startuptime = (45 * ADC_CLK + 5)/ 10000000;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));

    /* set the startup time */
    reg = ADCx->TIME;
    reg &= ~ADC_TIME_STARTUP_TIME;
    ADCx->TIME = reg | (startuptime << 8);
}

/**
  * @brief  Enables or disables the ADC discard bit.
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  NewState: new state of the ADCx peripheral.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_DiscardCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* enable the discard bit */
        ADCx->CR0 |= (uint32_t)ADC_CR0_DISCARD;
    }
    else
    {
        /* disable the discard bit */
        ADCx->CR0 &= (uint32_t)(~ADC_CR0_DISCARD);
    }
}

/**
  * @brief  Configures the high and low thresholds of the LEVEL.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  HighThreshold: the ADC analog watchdog High threshold value.
  *          This parameter must be a 12bit value.
  * @param  LowThreshold: the ADC analog watchdog Low threshold value.
  *          This parameter must be a 12bit value.
  * @retval None
  */
void ADC_ThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_THRESHOLD(HighThreshold));
    assert_param(IS_ADC_THRESHOLD(LowThreshold));

    /* Set the ADCx high and low threshold */
    ADCx->THRESHOLD = LowThreshold | ((uint32_t)HighThreshold << 16);

}

/**
  * @brief  Configures the reg compare.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the Continuous mode.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_RegCompareConfig(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* Enable the reg compare */
        ADCx->CR1 |= (uint32_t)ADC_CR1_REGCMP;
    }
    else
    {
        /* Disable the reg compare */
        ADCx->CR1 &= (uint32_t)(~ADC_CR1_REGCMP);
    }
}

/**
  * @brief  Configures the hht compare.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the Continuous mode.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_HHtCompareConfig(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* Enable the hht compare */
        ADCx->CR1 |= (uint32_t)ADC_CR1_HTCMP;
    }
    else
    {
        /* Disable the hht compare */
        ADCx->CR1 &= (uint32_t)(~ADC_CR1_HTCMP);
    }
}

/**
  * @brief  Configures the llt compare.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the Continuous mode.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_LLtCompareConfig(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* Enable the llt compare */
        ADCx->CR1 |= (uint32_t)ADC_CR1_LTCMP;
    }
    else
    {
        /* Disable the llt compare */
        ADCx->CR1 &= (uint32_t)(~ADC_CR1_LTCMP);
    }
}

/**
  * @brief  Configures the Acc Function.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the Continuous mode.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_AccCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* Enable the Acc */
        ADCx->CR1 |= (uint32_t)ADC_CR1_RACCEN;
    }
    else
    {
        /* Disable the Acc */
        ADCx->CR1 &= (uint32_t)(~ADC_CR1_RACCEN);
    }
}

/**
  * @brief  clear the Acc result register.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @retval None
  */
void ADC_AccResultClear(ADC_TypeDef* ADCx)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));

    /* Clear the Acc result */
    ADCx->CR1 |= ADC_CR1_RACC_CLR;
}

/**
  * @brief  Configures for the selected ADC channel.
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  ADC_Chn:  select the channel.
  *          This parameter can be one of the following values:
  *            @arg ADC_SIGNALChannel_0: select channel 0
  *            @arg ADC_SIGNALChannel_1: select channel 1
  *            @arg ADC_SIGNALChannel_2: select channel 2
  *            @arg ADC_SIGNALChannel_3: select channel 3
  *            @arg ADC_SIGNALChannel_4: select channel 4
  *            @arg ADC_SIGNALChannel_5: select channel 5
  *            @arg ADC_SIGNALChannel_6: select channel 6
  *            @arg ADC_SIGNALChannel_7: select channel 7
  * @retval None
  */
void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint16_t ADC_Chn)
{
    uint32_t reg;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_SIGNALCHANNEL(ADC_Chn));

    reg = ADCx->CR0;

    reg &= ~ADC_CR0_CHSEL;

    ADCx->CR0 = reg | ADC_Chn;
}

/**
  * @brief  Configures for the selected ADC channel.
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  ADC_Chn:  select the channel.
  *          This parameter can be one of the following values:
  *            @arg ADC_Channel_0: select channel 0
  *            @arg ADC_Channel_1: select channel 1
  *            @arg ADC_Channel_2: select channel 2
  *            @arg ADC_Channel_3: select channel 3
  *            @arg ADC_Channel_4: select channel 4
  *            @arg ADC_Channel_5: select channel 5
  *            @arg ADC_Channel_6: select channel 6
  *            @arg ADC_Channel_7: select channel 7
  *            @arg ADC_Channel_ALL: select channel 0~7
  * @retval None
  */
void ADC_ContinuousModeChannelConfig(ADC_TypeDef* ADCx, uint16_t ADC_Chn)
{
    uint32_t reg;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_CHANNEL(ADC_Chn));

    reg = ADCx->CR2;

    reg &= ~ADC_CR2_CHEN;

    ADCx->CR2 = reg | ADC_Chn;
}

/**
  * @brief  set the Continuous tsain hold time.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  SampleTime: set the tsain hold time.
  *          This parameter can be one of the following values:
  *            @when 12bit: the value can be 2~11;
  *            @when 10bit: the value can be 2~9;
  * @note
  * @retval None
  */
void ADC_SetContinuousBurstSampleTime(ADC_TypeDef* ADCx, uint8_t SampleTime)
{
    uint32_t reg;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));

    /* set the tsain hold time */
    reg = ADCx->TIME;
    reg &= ~ADC_TIME_BURST_SAMPLE;
    ADCx->TIME = reg | (SampleTime << 4);
}

/**
  * @brief  Enable the Continuous mode for the selected ADCx channels.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the Continuous mode.
  *          This parameter can be: ENABLE or DISABLE.
  * @note   It is not possible to have both discontinuous mode and continuous mode
  *         enabled. In this case (If DISCEN and CONT are Set), the ADC behaves
  *         as if continuous mode was disabled
  * @retval None
  */
void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* Enable the Continuous mode*/
        ADCx->CR1 |= (uint32_t)ADC_CR1_CT;
    }
    else
    {
        /* Disable the Continuous mode */
        ADCx->CR1 &= (uint32_t)(~ADC_CR1_CT);
    }
}

/**
  * @brief  Set the Continuous conversion number for the selected ADCx channels.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  Number: conversion count.
  *          This parameter can be one of the following values:
  *            @when 8bit: the value can be 0~255;
  * @retval None
  */
void ADC_SetContinuousConversionNumber(ADC_TypeDef* ADCx, uint8_t Number)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_CONTINUOUS_CONV_CNT(Number));

    ADCx->CR2 &= ~ADC_CR2_ADCCNT;
	
    ADCx->CR2 |= (Number << 8);
}

/**
  * @brief  Start Conversion for the selected ADC channels.
  * @note   In continuous mode, ADSTART is not cleared by hardware with the
  *         assertion of EOSEQ because the sequence is automatic relaunched
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @retval None
  */
void ADC_StartOfConversion(ADC_TypeDef* ADCx)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));

    ADCx->CR0 |= ADC_CR0_START;
}

/**
  * @brief  Returns the last ADCx conversion result data for ADC channel.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @retval The Data conversion value.
  */
uint32_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));

    /* Return the selected ADC conversion value */
    return (uint32_t) ADCx->RESULT;
}

/**
  * @brief  Returns the last ADCx conversion result data for ADC channel.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  ADC_Chn:  select the channel.
  *          This parameter can be one of the following values:
  *            @arg ADC_Channel_0: select channel 0
  *            @arg ADC_Channel_1: select channel 1
  *            @arg ADC_Channel_2: select channel 2
  *            @arg ADC_Channel_3: select channel 3
  *            @arg ADC_Channel_4: select channel 4
  *            @arg ADC_Channel_5: select channel 5
  *            @arg ADC_Channel_6: select channel 6
  *            @arg ADC_Channel_7: select channel 7
  * @retval The Data conversion value.
  */
uint32_t ADC_GetChnResultValue(ADC_TypeDef* ADCx, uint16_t ADC_Chn)
{
    uint32_t result;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_CHANNEL(ADC_Chn));

    switch(ADC_Chn)
    {
    case ADC_Channel_0:
        result = ADCx->RESULT0;
        break;
    case ADC_Channel_1:
        result = ADCx->RESULT1;
        break;
    case ADC_Channel_2:
        result = ADCx->RESULT2;
        break;
    case ADC_Channel_3:
        result = ADCx->RESULT3;
        break;
    case ADC_Channel_4:
        result = ADCx->RESULT4;
        break;
    case ADC_Channel_5:
        result = ADCx->RESULT5;
        break;
    case ADC_Channel_6:
        result = ADCx->RESULT6;
        break;
    case ADC_Channel_7:
        result = ADCx->RESULT7;
        break;
    default:
        result = ADCx->RESULT;
        break;
    }

    /* Return the selected ADC conversion value */
    return result;
}

/**
  * @brief  Returns the last ADCx conversion result ACC data for ADC channel.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @retval The Data conversion value.
  */
uint32_t ADC_GetAccResultValue(ADC_TypeDef* ADCx)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));

    /* Return the selected ADC conversion value */
    return (uint32_t) ADCx->RESULT_ACC;
}

/**
  * @}
  */

/**
  * @brief  Enables or disables the specified ADC DMA request.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the selected ADC DMA transfer.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));

    if (NewState != DISABLE)
    {
        /* Enable the selected ADC DMA request */
        ADCx->CR2 |= (uint32_t)ADC_CR2_DMAEN;
    }
    else
    {
        /* Disable the selected ADC DMA request */
        ADCx->CR2 &= (uint32_t)(~ADC_CR2_DMAEN);
    }
}

/**
  * @}
  */

/**
  * @brief  Enables or disables the specified ADC interrupts.
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  ADC_IT: specifies the ADC interrupt sources to be enabled or disabled.
  *          This parameter can be one of the following values:
  *            @arg ADC_IT_CONT: convertion interrupt
  *            @arg ADC_IT_REG: result compare interrupt
  *            @arg ADC_IT_HHT: ADC high level compare interrupt
  *            @arg ADC_IT_LLT: ADC low level compare interrupt
  *            @arg ADC_IT_RIS7: ADC channel interrupt
  *            @arg ADC_IT_RIS6: ADC channel interrupt
  *            @arg ADC_IT_RIS5: ADC channel interrupt
  *            @arg ADC_IT_RIS4: ADC channel interrupt
  *            @arg ADC_IT_RIS3: ADC channel interrupt
  *            @arg ADC_IT_RIS2: ADC channel interrupt
  *            @arg ADC_IT_RIS1: ADC channel interrupt
  *            @arg ADC_IT_RIS0: ADC channel interrupt
  * @param  NewState: new state of the specified ADC interrupts.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_ITConfig(ADC_TypeDef* ADCx, uint32_t ADC_IT, FunctionalState NewState)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_FUNCTIONAL_STATE(NewState));
    assert_param(IS_ADC_CONFIG_IT(ADC_IT));

    if (NewState != DISABLE)
    {
        /* Enable the selected ADC interrupts */
        ADCx->INTEN |= ADC_IT;
    }
    else
    {
        /* Disable the selected ADC interrupts */
        ADCx->INTEN &= (~(uint32_t)ADC_IT);
    }
}

/**
  * @brief  Checks whether the specified ADC flag is set or not.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  ADC_FLAG: specifies the flag to check.
  *          This parameter can be one of the following values:
  *            @arg ADC_FLAG_ADRDY: ADC Ready flag
  *            @arg ADC_FLAG_START: End of conversion flag
  *            @arg ADC_FLAG_CONT: convertion flag
  *            @arg ADC_FLAG_REG: result compare flag
  *            @arg ADC_FLAG_HHT: ADC high level compare flag
  *            @arg ADC_FLAG_LLT: ADC low level compare flag
  *            @arg ADC_FLAG_RIS7: ADC channel flag
  *            @arg ADC_FLAG_RIS6: ADC channel flag
  *            @arg ADC_FLAG_RIS5: ADC channel flag
  *            @arg ADC_FLAG_RIS4: ADC channel flag
  *            @arg ADC_FLAG_RIS3: ADC channel flag
  *            @arg ADC_FLAG_RIS2: ADC channel flag
  *            @arg ADC_FLAG_RIS1: ADC channel flag
  *            @arg ADC_FLAG_RIS0: ADC channel flag
  * @retval The new state of ADC_FLAG (SET or RESET).
  */
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint32_t ADC_FLAG)
{
    FlagStatus bitstatus = RESET;
    uint32_t tmpreg = 0;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_GET_FLAG(ADC_FLAG));

    if((uint32_t)(ADC_FLAG & 0x01000000))
    {
        tmpreg = ADCx->CR0 & 0xFEFFFFFF;
    }
    else if((uint32_t)(ADC_FLAG & 0x02000000))
    {
        tmpreg = ADCx->CR2 & 0xFDFFFFFF;
    }
    else
    {
        tmpreg = ADCx->RAWINTSR;
    }

    /* Check the status of the specified ADC flag */
    if ((tmpreg & ADC_FLAG) != (uint32_t)RESET)
    {
        /* ADC_FLAG is set */
        bitstatus = SET;
    }
    else
    {
        /* ADC_FLAG is reset */
        bitstatus = RESET;
    }
    /* Return the ADC_FLAG status */
    return  bitstatus;
}

/**
  * @brief  Clears the ADCx's pending flags.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  ADC_FLAG: specifies the flag to clear.
  *          This parameter can be any combination of the following values:
  *            @arg ADC_FLAG_CONT: convertion flag
  *            @arg ADC_FLAG_REG: result compare flag
  *            @arg ADC_FLAG_HHT: ADC high level compare flag
  *            @arg ADC_FLAG_LLT: ADC low level compare flag
  *            @arg ADC_FLAG_RIS7: ADC channel flag
  *            @arg ADC_FLAG_RIS6: ADC channel flag
  *            @arg ADC_FLAG_RIS5: ADC channel flag
  *            @arg ADC_FLAG_RIS4: ADC channel flag
  *            @arg ADC_FLAG_RIS3: ADC channel flag
  *            @arg ADC_FLAG_RIS2: ADC channel flag
  *            @arg ADC_FLAG_RIS1: ADC channel flag
  *            @arg ADC_FLAG_RIS0: ADC channel flag
  * @retval None
  */
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint32_t ADC_FLAG)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG));

    /* Clear the selected ADC flags */
    ADCx->RAWINTSR &= (uint32_t)~ADC_FLAG;
}

/**
  * @brief  Checks whether the specified ADC interrupt has occurred or not.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral
  * @param  ADC_IT: specifies the ADC interrupt source to check.
  *          This parameter can be one of the following values:
  *            @arg ADC_IT_CONT: convertion interrupt
  *            @arg ADC_IT_REG: result compare interrupt
  *            @arg ADC_IT_HHT: ADC high level compare interrupt
  *            @arg ADC_IT_LLT: ADC low level compare interrupt
  *            @arg ADC_IT_RIS7: ADC channel interrupt
  *            @arg ADC_IT_RIS6: ADC channel interrupt
  *            @arg ADC_IT_RIS5: ADC channel interrupt
  *            @arg ADC_IT_RIS4: ADC channel interrupt
  *            @arg ADC_IT_RIS3: ADC channel interrupt
  *            @arg ADC_IT_RIS2: ADC channel interrupt
  *            @arg ADC_IT_RIS1: ADC channel interrupt
  *            @arg ADC_IT_RIS0: ADC channel interrupt
  * @retval The new state of ADC_IT (SET or RESET).
  */
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint32_t ADC_IT)
{
    ITStatus bitstatus = RESET;
    uint32_t enablestatus = 0;

    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_GET_IT(ADC_IT));

    /* Get the ADC_IT enable bit status */
    enablestatus = (uint32_t)(ADCx->INTEN & ADC_IT);

    /* Check the status of the specified ADC interrupt */
    if (((uint32_t)(ADCx->RAWINTSR & ADC_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
    {
        /* ADC_IT is set */
        bitstatus = SET;
    }
    else
    {
        /* ADC_IT is reset */
        bitstatus = RESET;
    }
    /* Return the ADC_IT status */
    return  bitstatus;
}

/**
  * @brief  Clears the ADCx's interrupt pending bits.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  ADC_IT: specifies the ADC interrupt pending bit to clear.
  *          This parameter can be one of the following values:
  *            @arg ADC_IT_CONT: convertion interrupt
  *            @arg ADC_IT_REG: result compare interrupt
  *            @arg ADC_IT_HHT: ADC high level compare interrupt
  *            @arg ADC_IT_LLT: ADC low level compare interrupt
  *            @arg ADC_IT_RIS7: ADC channel interrupt
  *            @arg ADC_IT_RIS6: ADC channel interrupt
  *            @arg ADC_IT_RIS5: ADC channel interrupt
  *            @arg ADC_IT_RIS4: ADC channel interrupt
  *            @arg ADC_IT_RIS3: ADC channel interrupt
  *            @arg ADC_IT_RIS2: ADC channel interrupt
  *            @arg ADC_IT_RIS1: ADC channel interrupt
  *            @arg ADC_IT_RIS0: ADC channel interrupt
  * @retval None
  */
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint32_t ADC_IT)
{
    /* Check the parameters */
    assert_param(IS_ADC_ALL_PERIPH(ADCx));
    assert_param(IS_ADC_CLEAR_IT(ADC_IT));

    /* Clear the selected ADC interrupt pending bits */
    ADCx->RAWINTSR &= (uint32_t)~ADC_IT;
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */


/************************ (C) COPYRIGHT CHIPAT *****END OF FILE****/
